🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / app / src / main / java / com / geeksville / mesh / repository / radio / StreamInterface.kt
Displaying Raw • Download
app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt 78274c792318331b11ab64cd28e58e829875b8c2 (78274c79) Text, 5.38 KB
T8b949e/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787com.geeksville.mesh.repository.radio
Tff7b72import T7ee787timber.log.Timber
T8b949e/**
* An interface that assumes we are talking to a meshtastic device over some sort of stream connection (serial or TCP
* probably)
*/
Tff7b72abstract Tff7b72class T56d364StreamInterfaceTb4b4b4(Tff7b72protected Tff7b72val Te6edf3serviceTb4b4b4: Te6edf3RadioInterfaceServiceTb4b4b4) Tb4b4b4: Te6edf3IRadioInterface Tb4b4b4{
Tff7b72companion Tff7b72object Tb4b4b4{
Tff7b72private Tff7b72const Tff7b72val Te6edf3START1 Tff7b72= T79c0ff0Te6edf3x94Tb4b4b4.Te6edf3toByteTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72const Tff7b72val Te6edf3START2 Tff7b72= T79c0ff0Te6edf3xc3Tb4b4b4.Te6edf3toByteTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72const Tff7b72val Te6edf3MAX_TO_FROM_RADIO_SIZE Tff7b72= T79c0ff5T79c0ff1T79c0ff2
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3debugLineBuf Tff7b72= Te6edf3kotlinTb4b4b4.Te6edf3textTb4b4b4.Te6edf3StringBuilderTb4b4b4(Tb4b4b4)
T8b949e/** The index of the next byte we are hoping to receive */
Tff7b72private Tff7b72var Te6edf3ptr Tff7b72= T79c0ff0
T8b949e/** The two halves of our length */
Tff7b72private Tff7b72var Te6edf3msb Tff7b72= T79c0ff0
Tff7b72private Tff7b72var Te6edf3lsb Tff7b72= T79c0ff0
Tff7b72private Tff7b72var Te6edf3packetLen Tff7b72= T79c0ff0
Tff7b72override Tff7b72fun Td2a8ffcloseTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffClosing stream for goodTa5d6ff"Tb4b4b4)
Te6edf3onDeviceDisconnectTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4}
T8b949e/**
* Tell MeshService our device has gone away, but wait for it to come back
*
* @param waitForStopped if true we should wait for the manager to finish - must be false if called from inside the
* manager callbacks
*/
Tff7b72protected Tff7b72open Tff7b72fun Td2a8ffonDeviceDisconnectTb4b4b4(Te6edf3waitForStoppedTb4b4b4: Tffa657BooleanTb4b4b4) Tb4b4b4{
Te6edf3serviceTb4b4b4.Te6edf3onDisconnectTb4b4b4(
Te6edf3isPermanent Tff7b72= Tff7b72trueTb4b4b4,
Tb4b4b4) T8b949e// if USB device disconnects it is definitely permanently gone, not sleeping)
Tb4b4b4}
Tff7b72protected Tff7b72open Tff7b72fun Td2a8ffconnectTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Before telling mesh service, send a few START1s to wake a sleeping device
Tff7b72val Te6edf3wakeBytes Tff7b72= Te6edf3byteArrayOfTb4b4b4(Te6edf3START1Tb4b4b4, Te6edf3START1Tb4b4b4, Te6edf3START1Tb4b4b4, Te6edf3START1Tb4b4b4)
Te6edf3sendBytesTb4b4b4(Te6edf3wakeBytesTb4b4b4)
T8b949e// Now tell clients they can (finally use the api)
Te6edf3serviceTb4b4b4.Te6edf3onConnectTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72abstract Tff7b72fun Td2a8ffsendBytesTb4b4b4(Te6edf3pTb4b4b4: Te6edf3ByteArrayTb4b4b4)
T8b949e// If subclasses need to flash at the end of a packet they can implement
Tff7b72open Tff7b72fun Td2a8ffflushBytesTb4b4b4(Tb4b4b4) Tb4b4b4{Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffhandleSendToRadioTb4b4b4(Te6edf3pTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tb4b4b4{
T8b949e// This method is called from a continuation and it might show up late, so check for uart being null
Tff7b72val Te6edf3header Tff7b72= Te6edf3ByteArrayTb4b4b4(T79c0ff4Tb4b4b4)
Te6edf3headerTff7b72[T79c0ff0Tff7b72] Tff7b72= Te6edf3START1
Te6edf3headerTff7b72[T79c0ff1Tff7b72] Tff7b72= Te6edf3START2
Te6edf3headerTff7b72[T79c0ff2Tff7b72] Tff7b72= Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3size Te6edf3shr T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3toByteTb4b4b4(Tb4b4b4)
Te6edf3headerTff7b72[T79c0ff3Tff7b72] Tff7b72= Tb4b4b4(Te6edf3pTb4b4b4.Te6edf3size Te6edf3and T79c0ff0Te6edf3xffTb4b4b4)Tb4b4b4.Te6edf3toByteTb4b4b4(Tb4b4b4)
Te6edf3sendBytesTb4b4b4(Te6edf3headerTb4b4b4)
Te6edf3sendBytesTb4b4b4(Te6edf3pTb4b4b4)
Te6edf3flushBytesTb4b4b4(Tb4b4b4)
Tb4b4b4}
T8b949e/** Print device serial debug output somewhere */
Tff7b72private Tff7b72fun Td2a8ffdebugOutTb4b4b4(Te6edf3bTb4b4b4: Tffa657ByteTb4b4b4) Tb4b4b4{
Tff7b72when Tb4b4b4(Tff7b72val Te6edf3c Tff7b72= Te6edf3bTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toCharTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Ta5d6ff'\r' Tff7b72-Tff7b72> Tb4b4b4{Tb4b4b4} T8b949e// ignore
Ta5d6ff'\n' Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3dTb4b4b4(Ta5d6ff"Ta5d6ffDeviceLog: Tffd700$Te6edf3debugLineBufTa5d6ff"Tb4b4b4)
Te6edf3debugLineBufTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Te6edf3debugLineBufTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3cTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3rxPacket Tff7b72= Te6edf3ByteArrayTb4b4b4(Te6edf3MAX_TO_FROM_RADIO_SIZETb4b4b4)
Tff7b72protected Tff7b72fun Td2a8ffreadCharTb4b4b4(Te6edf3cTb4b4b4: Tffa657ByteTb4b4b4) Tb4b4b4{
T8b949e// Assume we will be advancing our pointer
Tff7b72var Te6edf3nextPtr Tff7b72= Te6edf3ptr Tff7b72+ T79c0ff1
Tff7b72fun Td2a8fflostSyncTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TimberTb4b4b4.Te6edf3eTb4b4b4(Ta5d6ff"Ta5d6ffLost protocol syncTa5d6ff"Tb4b4b4)
Te6edf3nextPtr Tff7b72= T79c0ff0
Tb4b4b4}
T8b949e// Deliver our current packet and restart our reader
Tff7b72fun Td2a8ffdeliverPacketTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3buf Tff7b72= Te6edf3rxPacketTb4b4b4.Te6edf3copyOfTb4b4b4(Te6edf3packetLenTb4b4b4)
Te6edf3serviceTb4b4b4.Te6edf3handleFromRadioTb4b4b4(Te6edf3bufTb4b4b4)
Te6edf3nextPtr Tff7b72= T79c0ff0 T8b949e// Start parsing the next packet
Tb4b4b4}
Tff7b72when Tb4b4b4(Te6edf3ptrTb4b4b4) Tb4b4b4{
T79c0ff0 Tff7b72-Tff7b72> T8b949e// looking for START1
Tff7b72if Tb4b4b4(Te6edf3c Tff7b72!Tff7b72= Te6edf3START1Tb4b4b4) Tb4b4b4{
Te6edf3debugOutTb4b4b4(Te6edf3cTb4b4b4)
Te6edf3nextPtr Tff7b72= T79c0ff0 T8b949e// Restart from scratch
Tb4b4b4}
T79c0ff1 Tff7b72-Tff7b72> T8b949e// Looking for START2
Tff7b72if Tb4b4b4(Te6edf3c Tff7b72!Tff7b72= Te6edf3START2Tb4b4b4) Tb4b4b4{
Te6edf3lostSyncTb4b4b4(Tb4b4b4) T8b949e// Restart from scratch
Tb4b4b4}
T79c0ff2 Tff7b72-Tff7b72> T8b949e// Looking for MSB of our 16 bit length
Te6edf3msb Tff7b72= Te6edf3cTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4) Te6edf3and T79c0ff0Te6edf3xff
T79c0ff3 Tff7b72-Tff7b72> Tb4b4b4{ T8b949e// Looking for LSB of our 16 bit length
Te6edf3lsb Tff7b72= Te6edf3cTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4) Te6edf3and T79c0ff0Te6edf3xff
T8b949e// We've read our header, do one big read for the packet itself
Te6edf3packetLen Tff7b72= Tb4b4b4(Te6edf3msb Te6edf3shl T79c0ff8Tb4b4b4) Te6edf3or Te6edf3lsb
Tff7b72if Tb4b4b4(Te6edf3packetLen Tff7b72> Te6edf3MAX_TO_FROM_RADIO_SIZETb4b4b4) Tb4b4b4{
Te6edf3lostSyncTb4b4b4(Tb4b4b4) T8b949e// If packet len is too long, the bytes must have been corrupted, start looking for
T8b949e// START1 again
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetLen Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3deliverPacketTb4b4b4(Tb4b4b4) T8b949e// zero length packets are valid and should be delivered immediately (because there
T8b949e// won't be a next byte of payload)
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Tb4b4b4{
T8b949e// We are looking at the packet bytes now
Te6edf3rxPacketTff7b72[Te6edf3ptr Tff7b72- T79c0ff4Tff7b72] Tff7b72= Te6edf3c
T8b949e// Note: we have to check if ptr +1 is equal to packet length (for example, for a 1 byte packetlen, this
T8b949e// code will be run with ptr of4
Tff7b72if Tb4b4b4(Te6edf3ptr Tff7b72- T79c0ff4 Tff7b72+ T79c0ff1 Tff7b72=Tff7b72= Te6edf3packetLenTb4b4b4) Tb4b4b4{
Te6edf3deliverPacketTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3ptr Tff7b72= Te6edf3nextPtr
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.06s